package com.qqt.csr.im.socketio.config;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import com.corundumstudio.socketio.scheduler.CancelableScheduler;
import com.qqt.csr.im.socketio.channel.SocketIOChannelInitializer;
import com.qqt.csr.im.socketio.listener.IMAuthorizationListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

/**
 * @Author: yang hao
 * @Date: 2024/10/15 14:31
 * @Description: socket-io 配置类
 **/
@Component
public class SocketIOConfig {

    // @Value("${socketio.host}")
    // private String host;

    @Value("${socketio.port}")
    private Integer port;

    @Value("${socketio.maxFramePayloadLength}")
    private int maxFramePayloadLength;

    @Value("${socketio.maxHttpContentLength}")
    private int maxHttpContentLength;

    @Value("${socketio.bossCount}")
    private int bossCount;

    @Value("${socketio.workCount}")
    private int workCount;

    @Value("${socketio.allowCustomRequests}")
    private boolean allowCustomRequests;

    @Value("${socketio.upgradeTimeout}")
    private int upgradeTimeout;

    @Value("${socketio.pingTimeout}")
    private int pingTimeout;

    @Value("${socketio.pingInterval}")
    private int pingInterval;
    @Autowired
    private IMAuthorizationListener authorizationListener;

    @Bean
    public SocketIOServer socketServer() {
        Configuration configuration = new Configuration();
        configuration.setPort(port);
        configuration.setMaxFramePayloadLength(maxFramePayloadLength);
        configuration.setMaxHttpContentLength(maxHttpContentLength);
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setReuseAddress(true);
        configuration.setSocketConfig(socketConfig);
        configuration.setOrigin(null);
        configuration.setBossThreads(bossCount);
        configuration.setWorkerThreads(workCount);
        configuration.setAllowCustomRequests(allowCustomRequests);
        configuration.setUpgradeTimeout(upgradeTimeout);
        configuration.setPingTimeout(pingTimeout);
        configuration.setPingInterval(pingInterval);
        configuration.setRandomSession(true);
        configuration.setAuthorizationListener(authorizationListener);

        SocketIOServer socketIOServer = new SocketIOServer(configuration);

        ReflectionUtils.doWithFields(SocketIOServer.class, field -> {
            field.setAccessible(true);
            com.corundumstudio.socketio.SocketIOChannelInitializer pipelineFactory = (com.corundumstudio.socketio.SocketIOChannelInitializer) field.get(socketIOServer);
            ReflectionUtils.doWithFields(com.corundumstudio.socketio.SocketIOChannelInitializer.class, schedulerField -> {
                schedulerField.setAccessible(true);
                ((CancelableScheduler) schedulerField.get(pipelineFactory)).shutdown();
            }, schedulerField -> schedulerField.getType().isAssignableFrom(CancelableScheduler.class));
        }, field -> field.getType().isAssignableFrom(com.corundumstudio.socketio.SocketIOChannelInitializer.class));

        socketIOServer.setPipelineFactory(new SocketIOChannelInitializer());
        return socketIOServer;
    }

    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }

}
